} Precedence;
typedef void (*ParseFn)();
typedef struct {
The table that drives our whole parser is an array of ParseRules. We’ve been
talking about it forever, and finally you get to see it.
ParseRule rules[] = {
[
TOKEN_LEFT_PAREN] = {grouping, NULL, PREC_NONE},
[
TOKEN_RIGHT_PAREN] = {NULL, NULL, PREC_NONE},
[
TOKEN_LEFT_BRACE] = {NULL, NULL, PREC_NONE},
[
TOKEN_RIGHT_BRACE] = {NULL, NULL, PREC_NONE},
[
TOKEN_COMMA] = {NULL, NULL, PREC_NONE},
[
TOKEN_DOT] = {NULL, NULL, PREC_NONE},
[
TOKEN_MINUS] = {unary, binary, PREC_TERM},
[
TOKEN_PLUS] = {NULL, binary, PREC_TERM},
[
TOKEN_SEMICOLON] = {NULL, NULL, PREC_NONE},
[
TOKEN_SLASH] = {NULL, binary, PREC_FACTOR},
[
TOKEN_STAR] = {NULL, binary, PREC_FACTOR},
[
TOKEN_BANG] = {NULL, NULL, PREC_NONE},
[
TOKEN_BANG_EQUAL] = {NULL, NULL, PREC_NONE},
[
TOKEN_EQUAL] = {NULL, NULL, PREC_NONE},
[
TOKEN_EQUAL_EQUAL] = {NULL, NULL, PREC_NONE},
[
TOKEN_GREATER] = {NULL, NULL, PREC_NONE},
[
TOKEN_GREATER_EQUAL] = {NULL, NULL, PREC_NONE},
[
TOKEN_LESS] = {NULL, NULL, PREC_NONE},
[
TOKEN_LESS_EQUAL] = {NULL, NULL, PREC_NONE},
[
TOKEN_IDENTIFIER] = {NULL, NULL, PREC_NONE},
[
TOKEN_STRING] = {NULL, NULL, PREC_NONE},
[
TOKEN_NUMBER] = {number, NULL, PREC_NONE},
[
TOKEN_AND] = {NULL, NULL, PREC_NONE},
[
TOKEN_CLASS] = {NULL, NULL, PREC_NONE},
[
TOKEN_ELSE] = {NULL, NULL, PREC_NONE},
[
TOKEN_FALSE] = {NULL, NULL, PREC_NONE},
[
TOKEN_FOR] = {NULL, NULL, PREC_NONE},
[
TOKEN_FUN] = {NULL, NULL, PREC_NONE},
[
TOKEN_IF] = {NULL, NULL, PREC_NONE},
[
TOKEN_NIL] = {NULL, NULL, PREC_NONE},
[
TOKEN_OR] = {NULL, NULL, PREC_NONE},
[
TOKEN_PRINT] = {NULL, NULL, PREC_NONE},
[
TOKEN_RETURN] = {NULL, NULL, PREC_NONE},
[
TOKEN_SUPER] = {NULL, NULL, PREC_NONE},
[
TOKEN_THIS] = {NULL, NULL, PREC_NONE},
[
TOKEN_TRUE] = {NULL, NULL, PREC_NONE},
[
TOKEN_VAR] = {NULL, NULL, PREC_NONE},
[
TOKEN_WHILE] = {NULL, NULL, PREC_NONE},
[
TOKEN_ERROR] = {NULL, NULL, PREC_NONE},
[
TOKEN_EOF] = {NULL, NULL, PREC_NONE},
};
You can see how grouping and unary are slotted into the prefix parser
column for their respective token types. In the next column, binary is wired
up to the four arithmetic infix operators. Those infix operators also have their
precedences set in the last column.
Aside from those, the rest of the table is full of NULL and PREC_NONE . Most of
those empty cells are because there is no expression associated with those
compiler.c
add after enum Precedence
<<
compiler.c
add after unary()
<<
This is what happens when you write your
VM in a language that was designed to be
compiled on a PDP-11.